﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Collections.Generic;
using Demo_G.O.S.E.ServerEngine.Item;
using Demo_G.O.S.E.ServerEngine.Common;
using Demo_G.O.S.E.ServerEngine.Mobile;
using System.Threading;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Map
{
    /// <summary>
    /// 
    /// </summary>
    internal class ObjectEnumerator : IPooledEnumerator, IDisposable
    {
        #region zh-CHS 枚举 | en enum
        /// <summary>
        /// 
        /// </summary>
        private enum Stage
        {
            BaseItem = 0x01,
            BaseMobile = 0x02
        }
        #endregion

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 地图
        /// </summary>
        private BaseMap m_BaseMap = null;
        /// <summary>
        /// 地图范围
        /// </summary>
        private Rectangle2D m_Bounds = Rectangle2D.ZeroRectangle2D;
        /// <summary>
        /// 需要枚举的对象
        /// </summary>
        private SectorEnumerator m_Enumerator = null;
        /// <summary>
        /// 1 = Items, 2 = Mobiles
        /// </summary>
        private Stage m_Stage;
        #endregion

        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseMap"></param>
        /// <param name="Bounds"></param>
        private ObjectEnumerator( BaseMap baseMap, Rectangle2D Bounds )
        {
            m_BaseMap = baseMap;
            m_Bounds = Bounds;
        }
        #endregion

        #region zh-CHS 共有静态方法 | en Public Static Methods
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static Queue<ObjectEnumerator> s_InstancePool = new Queue<ObjectEnumerator>();
        /// <summary>
        /// 
        /// </summary>
        private static object s_LockInstancePool = new object();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Map"></param>
        /// <param name="Bounds"></param>
        /// <returns></returns>
        public static ObjectEnumerator Instantiate( BaseMap baseMap, Rectangle2D Bounds )
        {
            ObjectEnumerator l_ObjectEnumerator = null;

            Monitor.Enter( s_LockInstancePool );
            {
                if ( s_InstancePool.Count > 0 )
                {
                    l_ObjectEnumerator = s_InstancePool.Dequeue();

                    l_ObjectEnumerator.m_BaseMap = baseMap;
                    l_ObjectEnumerator.m_Bounds = Bounds;
                }
            }
            Monitor.Exit( s_LockInstancePool );

            if ( l_ObjectEnumerator == null )
                l_ObjectEnumerator = new ObjectEnumerator( baseMap, Bounds );

            l_ObjectEnumerator.Reset();
            return l_ObjectEnumerator;
        }
        #endregion

        #region zh-CHS 接口实现 属性 | enInterface Implementation Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private IPooledEnumerable m_Enumerable = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public IPooledEnumerable Enumerable
        {
            get { return m_Enumerable; }
            set { m_Enumerable = value; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 当前数据
        /// </summary>
        private object m_Current = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public object Current
        {
            get { return m_Current; }
        }
        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            do
            {
                if ( m_Enumerator.MoveNext() )
                {
                    object xObject = m_Enumerator.Current;

                    BaseMobile l_BaseMobile = xObject as BaseMobile;
                    if ( l_BaseMobile != null && l_BaseMobile.Deleted == false && m_Bounds.Contains( l_BaseMobile.Location ) )
                    {
                        m_Current = xObject;
                        return true;
                    }
                    else
                    {
                        BaseItem l_BaseItem = xObject as BaseItem;
                        if ( l_BaseItem != null && l_BaseItem.Deleted == false && l_BaseItem.Parent == null && m_Bounds.Contains( l_BaseItem.Location ) )
                        {
                            m_Current = xObject;
                            return true;
                        }
                    }
                }
                else if ( m_Stage == Stage.BaseItem ) // 如果是1,表示是Items,现在获取Mobiles
                {
                    if ( m_Enumerator != null )
                        m_Enumerator.Release();

                    // 然后获取的是Mobiles
                    m_Enumerator = SectorEnumerator.Instantiate( m_BaseMap, m_Bounds, SectorType.Mobiles );
                    
                    m_Current = null;
                    m_Stage = Stage.BaseMobile;
                }
                else
                {
                    m_Current = null;
                    m_Stage = Stage.BaseItem;　// 完成全部的枚举Items和Mobiles

                    return false;
                }
            } while ( true );
        }

        /// <summary>
        /// 
        /// </summary>
        public void Reset()
        {
            // 代表当前先获取是Items
            m_Stage = Stage.BaseItem;
            m_Current = null;

            // 如果不为空, 则先释放它
            if ( m_Enumerator != null )
                m_Enumerator.Release();

            // 首先获取的是Items
            m_Enumerator = SectorEnumerator.Instantiate( m_BaseMap, m_Bounds, SectorType.Items );
            m_Enumerator.Enumerable = m_Enumerable;
        }

        /// <summary>
        /// 释放
        /// </summary>
        public void Release()
        {
            if ( m_BaseMap == null )
                return;
            else
            {
                m_BaseMap = null;
                m_Current = null;
                m_Enumerable = null;
                m_Stage = Stage.BaseItem;
                m_Bounds = Rectangle2D.ZeroRectangle2D;
            }

            if ( m_Enumerator != null )
            {
                m_Enumerator.Release();
                m_Enumerator = null;
            }

            Monitor.Enter( s_LockInstancePool );
            {
                s_InstancePool.Enqueue( this );
            }
            Monitor.Exit( s_LockInstancePool );
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Release();
        }
        #endregion
    }
}
#endregion

